#ifndef PARSESDT_H
#define PARSESDT_H
#include <stdio.h>
#include <string.h>

#define SDT_DESCRIPTOR_MAX 1024
#define SDT_EVENT_MAX 128
#define SDT_PROGRAM_NAME_LENGTH 512

typedef struct TS_SDT_SERVICE
{
    unsigned int service_id :16;
    unsigned int reserved_future_use :6;
    unsigned int EIT_schedule_flag :1;
    unsigned int EIT_present_following_flag :1; //0x0F
    unsigned int running_status :3;
    unsigned int free_CA_mode :1;
    unsigned int descriptors_loop_length :12;
    unsigned char descriptor[SDT_DESCRIPTOR_MAX];
} TS_SDT_SERVICE;

typedef struct TS_SDT
{
    unsigned int table_id :8;
    unsigned int section_syntax_indicator :1;
    unsigned int reserved_future_use_1 :1;
    unsigned int reserved_1 :2;
    unsigned int section_length :12;
    unsigned int transport_stream_id :16;
    unsigned int reserved_2 :2;
    unsigned int version_number :5;
    unsigned int current_next_indicator :1;
    unsigned int section_number :8;
    unsigned int last_section_number :8;
    unsigned int original_network_id :16;
    unsigned int reserved_future_use_2 :8;

    TS_SDT_SERVICE astSDT_Service[SDT_EVENT_MAX];

    unsigned int CRC_32 :32;
} TS_SDT;

/*----------------------------------------------------------*/
/* the information we want to get form the SDT table */
/*----------------------------------------------------------*/
typedef struct SDT_INFO
{
    unsigned int uiServiceId :16;
    unsigned int uiFreeCA_Mode :1;
    unsigned int aucProgramNanme[SDT_PROGRAM_NAME_LENGTH];
    unsigned int uiEIT_ScheduleFlag :1;
    unsigned int uiEIT_PresentFollowingFlag :1;
} SDT_INFO;


class ParseSDT
{
public:
    ~ParseSDT();
    ParseSDT(const ParseSDT&)=delete;
    ParseSDT& operator=(const ParseSDT&)=delete;
    static ParseSDT& get_instance();
    /*********************************************************************************************************************************
     * Function Name : ParseSDT_Table
     * Description   :  parse the SDT table
     * Parameters    :
     * 				pfTsFile -- the TS file descriptor
     * 				iTsPosition -- the TS package begin position
     *				iTsLength -- the TS package length
     *				pstSDT_Info -- the SDT_INFO array
     * Returns       : the count of the SDT_INFO count
     *********************************************************************************************************************************/
    int ParseSDT_Table(FILE *pfTsFile, int iTsPosition, int iTsLength, SDT_INFO *pstSDT_Info);
private:
    /*********************************************************************************************************************************
     * Function Name : ParseSDT_SectionHead
     * Description   :  parse the SDT section head
     * Parameters    :
     * 				pstTS_SDT -- the TS_SDT
     *				pucSectionBuffer -- the SDT section buffer
     * Returns       : void
     *********************************************************************************************************************************/
    void ParseSDT_SectionHead(TS_SDT *pstTS_SDT, unsigned char *pucSectionBuffer);
    /*********************************************************************************************************************************
     * Function Name : ParseSDT_Section
     * Description   :  parse the SDT section
     * Parameters    :
     * 				pstTS_SDT -- the TS_SDT
     *				pucSectionBuffer -- the SDT section buffer
     * Returns       : the TS_SDT_SERVICE count
     *********************************************************************************************************************************/
    int ParseSDT_Section(TS_SDT *pstTS_SDT, unsigned char *pucSectionBuffer);
    /*********************************************************************************************************************************
     * Function Name : GetSDT_Info
     * Description   :  get the SDT information (service_id and program_name)
     * Parameters    :
     * 				pstTS_SDT -- the TS_SDT
     * 				iServiceCount -- TS_SDT_SERVICE count
     *				pstSDT_Info -- the SDT_INFO array
     *				iInfoCount -- the SDT_INFO count
     * Returns       : void
     *********************************************************************************************************************************/
    void GetSDT_Info(TS_SDT *pstTS_SDT, int iServiceCount, SDT_INFO *pstSDT_Info, int *iInfoCount);

    /*********************************************************************************************************************************
     * Function Name : CleanSDT_Info
     * Description   :  clean SDT information
     * Parameters    :
     *				pstSDT_Info -- the SDT_INFO array
     *				piInfoCount -- the SDT_INFO count
     * Returns       :>0 - the count of the program -1 - failure 0 - no the section in the transport stream
     *********************************************************************************************************************************/
    void CleanSDT_Info(SDT_INFO *pstSDT_Info, int *piInfoCount);

private:
    ParseSDT();
};

#endif // PARSESDT_H
